'''
Created on 24/03/2009

@author: eh01
'''
from yarra.datastore.dsstub import DSStub
from yarra.event import eventconstants
from yarra.event.eventmanager import EventManager
from yarra.handler.connectivitytestrequesthandler import \
    ConnectivityTestHTTPRequestHandler, ConnectivityTestWebServiceRequestHandler
from yarra.handler.connectivitytestresponsehandler import \
    ConnectionTestHTTPResponseHandler, ConnectivityTestWebServiceResponseHandler
from yarra.handler.httperrorhandler import HTTPErrorHandler
from yarra.handler.httprequestgetindexhandler import HTTPRequestGETIndexHandler
from yarra.handler.httprequestgetstaticpagehandler import \
    HTTPRequestGETStaticPageHandler
from yarra.handler.huberrorhandler import HubErrorHandler
from yarra.handler.hubmessagehandler import HubMessageHandler
from yarra.handler.imhttpdelegaterequesthandler import \
    IMHTTPDelegateRequestHandler
from yarra.handler.imhttpresponsehandler import IMHTTPResponseHandler
from yarra.handler.publicapplicationstatusrequesthanlder import \
    PublicApplicationStatusHTTPRequestHandler, \
    PublicApplicationStatusWebServiceRequestHandler
from yarra.handler.publicapplicationstatusresponsehandler import \
    PublicApplicationStatusWebServiceResponseHandler, \
    PublicApplicationStatusTestHTTPResponseHandler
from yarra.handler.responsetimeouthandler import ResponseTimeoutHandler
from yarra.handler.sendtohubhandler import SendToHubHandler
from yarra.handler.speara2afaulthandler import \
    SPEARA2AFaultWebServiceResponseHandler, SPEARA2AFaultHTTPResponseHandler
from yarra.handler.speara2ahandler import SPEARA2AHandler
from yarra.logging import yarralogging
from yarra.nodeconfig import NodeConfig
from yarra.service.hub.hublistener import HubListener
from yarra.service.timer.timerservicemanager import TimerServiceManager
from yarra.service.webserver.nodehttpserver import NodeHTTPServer
import sys

class Initializer():

    __server = None
    __hub_listener = None
    __dsstub = None
    __logger = logger = yarralogging.get_logger()
    
    def initialize_db_stub(self):
        self.__dsstub = DSStub()
        imconfig = NodeConfig(config_file_absolute_path)
        self.__dsstub.set_IM_Config(imconfig)
        
    def initialize_event_manager(self):
        # override the default get_eventHandlers method at a class level for testing purposes
        instancemethodEventHandlers = type(EventManager.get_eventHandlers)
        EventManager.get_eventHandlers = instancemethodEventHandlers(get_eventHandlers_override, None, EventManager)
        eventManager = EventManager()
        eventManager.start()

    def initialize_web_server(self):
        self.__server = NodeHTTPServer(self.__dsstub.get_http_server_port())
        self.__server.start()   
    
    def initialize_hub_listener(self):
        self.__hub_listener = HubListener(self.__dsstub.get_node_id())
        self.__hub_listener.start()
        
    def initialize_timer_manager(self):
        timer_manager = TimerServiceManager()
        timer_manager.start()
        
    def shutdown_event_manager(self):
        EventManager().stop()
        
    def shutdown_web_server(self):
        self.__server.stop()
    
    def shutdown_hub_listener(self):
        self.__hub_listener.stop_listener()
    
    def shutdown_timer_manager(self):
        TimerServiceManager().stop()
        
    def initialize(self):
        self.initialize_db_stub()
        self.initialize_event_manager()
        self.initialize_web_server()
        self.initialize_hub_listener()
        self.initialize_timer_manager()
        self.__logger.info('Initialization Complete')
    
    def shutdown(self):
        self.shutdown_event_manager()
        self.shutdown_web_server()
        self.shutdown_hub_listener()
        self.shutdown_timer_manager()
        self.__logger.info('Shutdown Complete')

def get_eventHandlers_override(self):
    im_http_delegagte_request_handler = IMHTTPDelegateRequestHandler()
    http_request_get_static_page_handler = HTTPRequestGETStaticPageHandler()
    http_error_handler = HTTPErrorHandler()
    connectivity_test_request_handler = ConnectivityTestHTTPRequestHandler()
    im_http_response_handler = IMHTTPResponseHandler()
    send_to_hub_handler = SendToHubHandler()
    hub_message_handler = HubMessageHandler()
    connectivity_test_http_response_handler = ConnectionTestHTTPResponseHandler()
    connectivity_test_web_service_request_handler = ConnectivityTestWebServiceRequestHandler()
    spear_a2a_handler = SPEARA2AHandler()
    connectivity_test_web_service_response_handler = ConnectivityTestWebServiceResponseHandler()
    spear_a2a_fault_webservice_response_handler = SPEARA2AFaultWebServiceResponseHandler()
    spear_a2a_fault_http_response_handler = SPEARA2AFaultHTTPResponseHandler()
    hub_error_handler = HubErrorHandler()
    response_timeout_handler = ResponseTimeoutHandler()
    public_application_status_test_http_request_handler = PublicApplicationStatusHTTPRequestHandler()
    public_application_status_test_web_service_request_handler = PublicApplicationStatusWebServiceRequestHandler()
    public_application_status_test_web_service_response_handler = PublicApplicationStatusWebServiceResponseHandler()
    public_application_status_test_http_response_handler = PublicApplicationStatusTestHTTPResponseHandler()
    http_request_get_index_handler = HTTPRequestGETIndexHandler()
    eventHandlers = {
                     eventconstants.HTTP_REQUEST_EVENT_TYPE:im_http_delegagte_request_handler,
                     eventconstants.HTTP_REQUEST_GET_STATIC_PAGE:http_request_get_static_page_handler,
                     eventconstants.HTTP_ERROR_EVENT_TYPE:http_error_handler,
                     eventconstants.HTTP_REQUEST_POST_CONNECTIVITY_TEST_EVENT_TYPE:connectivity_test_request_handler,
                     eventconstants.CONNECTIVITY_TEST_REQUEST_EVENT_TYPE:connectivity_test_web_service_request_handler,
                     eventconstants.CONNECTIVITY_TEST_WEB_SERVICE_RESPONSE_EVENT_TYPE:connectivity_test_web_service_response_handler,
                     eventconstants.CONNECTIVITY_TEST_RESPONSE_EVENT_TYPE:connectivity_test_http_response_handler,
                     eventconstants.HTTP_REQUEST_POST_APPLICATION_STATUS_TEST_EVENT_TYPE:public_application_status_test_http_request_handler,
                     eventconstants.PUBLIC_APPLICATION_STATUS_TEST_REQUEST_EVENT_TYPE:public_application_status_test_web_service_request_handler,
                     eventconstants.PUBLIC_APPLICATION_STATUS_TEST_WEB_SERVICE_RESPONSE_EVENT_TYPE:public_application_status_test_web_service_response_handler,
                     eventconstants.PUBLIC_APPLICATION_STATUS_TEST_RESPONSE_MESSAGE_TYPE:public_application_status_test_http_response_handler,
                     eventconstants.HTTP_RESPONSE_EVENT_TYPE:im_http_response_handler,
                     eventconstants.SEND_TO_HUB_EVENT_TYPE:send_to_hub_handler,
                     eventconstants.HUB_MESSAGE_EVENT_TYPE:hub_message_handler,
                     eventconstants.SEND_TO_SPEAR_EVENT_TYPE:spear_a2a_handler,
                     eventconstants.SPEAR_A2A_FAULT_WEB_SERVICE_EVENT_TYPE:spear_a2a_fault_webservice_response_handler,
                     eventconstants.SPEAR_A2A_FAULT_HTTP_EVENT_TYPE:spear_a2a_fault_http_response_handler,
                     eventconstants.HUB_ERROR_EVENT_TYPE:hub_error_handler,
                     eventconstants.RESPONSE_TIMEOUT_EVENT_TYPE:response_timeout_handler,
                     eventconstants.HTTP_REQUEST_GET_INDEX_EVENT_TYPE:http_request_get_index_handler
                     }        
    return eventHandlers

if __name__ == '__main__':
    
    logger = yarralogging.get_logger()
    config_file_absolute_path = sys.argv[1]
    initializer = None
    try:
        initializer = Initializer()
        initializer.initialize()
        if DSStub().is_allow_keyboard_interrupt():
            # wait for KeyboardInterrupts
            sys.stdin.read()
            logger.info('Stopping')
    except KeyboardInterrupt:
        initializer.shutdown()